package com.csun.cmny.provider.service.impl;

import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.controller.websocket.WebSocketUtils;
import com.csun.cmny.provider.dao.DmcDeviceOnlineRecordMapper;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.constant.OnlineConstant;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.deviceOnlineRecord.DeviceOnlineQueryDto;
import com.csun.cmny.provider.model.enums.device.DmcDeviceAlertTypeEnum;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PublicUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcDeviceOnlineRecordServiceImpl extends BaseService<DmcDeviceOnlineRecord> implements DmcDeviceOnlineRecordService {
    @Resource
    private DmcDeviceOnlineRecordMapper dmcDeviceOnlineRecordMapper;
    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private DmcCsunCameraLocationService dmcCsunCameraLocationService;
    @Resource
    private DmcCsunBodySensorLocationService dmcCsunBodySensorLocationService;
    @Resource
    private DmcCsunHumidistatLocationService dmcCsunHumidistatLocationService;
    @Resource
    private DmcSleepCareBindService dmcSleepCareBindService;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;
    @Resource
    private JPushService jPushService;
    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private WebSocketUtils webSocketUtils;
    @Override
    public List<DmcDeviceOnlineRecord> queryListWithPage(DeviceOnlineQueryDto deviceOnlineQueryDto) {
        return dmcDeviceOnlineRecordMapper.queryListWithPage(deviceOnlineQueryDto);
    }

    @Override
    public Integer insertRecordByDeviceNo(String deviceNo,Integer online) {
        DmcDevice dmcDevice = new DmcDevice();
        DmcDeviceOnlineRecord dmcDeviceOnlineRecord = new DmcDeviceOnlineRecord();
        dmcDevice.setDeviceNo(deviceNo);
        List<DmcDevice> devices = dmcDeviceService.select(dmcDevice);
        if(PublicUtil.isNotEmpty(devices)){
            DmcDevice device = devices.get(0);
//            dmcDeviceOnlineRecord.setId(device.getId());
            dmcDeviceOnlineRecord.setDeviceId(device.getId());
            dmcDeviceOnlineRecord.setDeviceNo(device.getDeviceNo());
            dmcDeviceOnlineRecord.setDeviceType(device.getDeviceType());
            dmcDeviceOnlineRecord.setOnline(online);
            dmcDeviceOnlineRecord.setGroupId(device.getGroupId());
            dmcDeviceOnlineRecord.setDeviceName(device.getDeviceName());
            dmcDeviceOnlineRecord.setCreatedTime(new Date());

            switch (device.getDeviceType()){
                case DeviceConstant.CSUN_SLEEP:
                    DmcSleepCareBind dmcSleepCareBind = dmcSleepCareBindService.selectByKey(device.getId());
                    if (PublicUtil.isNotEmpty(dmcSleepCareBind)){
                        dmcDeviceOnlineRecord.setDeviceLocation(dmcSleepCareBind.getLocation());
                    }
                    break;
                case DeviceConstant.CSUN_BODY_SENSOR:
                    DmcCsunBodySensorLocation dmcCsunBodySensorLocation = dmcCsunBodySensorLocationService.selectByKey(device.getId());
                    if(PublicUtil.isNotEmpty(dmcCsunBodySensorLocation)){
                        dmcDeviceOnlineRecord.setDeviceLocation(dmcCsunBodySensorLocation.getLocation());
                    }
                    break;
                case DeviceConstant.NEWBODY :
                    DmcCsunBodySensorLocation newBodySensor = dmcCsunBodySensorLocationService.selectByKey(device.getId());
                    if(PublicUtil.isNotEmpty(newBodySensor)){
                        dmcDeviceOnlineRecord.setDeviceLocation(newBodySensor.getLocation());
                    }
                    break;
                case DeviceConstant.CSUN_CAMERA:
                    DmcCsunCameraLocation dmcCsunCameraLocation = dmcCsunCameraLocationService.selectByKey(device.getId());
                    if(PublicUtil.isNotEmpty(dmcCsunCameraLocation)){
                        dmcDeviceOnlineRecord.setDeviceLocation(dmcCsunCameraLocation.getLocation());
                    }
                    break;
                case DeviceConstant.HUMIDISTAT:
                    DmcCsunHumidistatLocation dmcCsunHumidistatLocation = dmcCsunHumidistatLocationService.selectByKey(device.getId());
                    if ((PublicUtil.isNotEmpty(dmcCsunHumidistatLocation))){
                        dmcDeviceOnlineRecord.setDeviceLocation(dmcCsunHumidistatLocation.getLocation());
                    }
                    break;
            }
        }

        if(PublicUtil.isNotEmpty(dmcDeviceOnlineRecord)){
            //若设备上线，如果存在该设备离线报警记录则标记为已处理
            if(dmcDeviceOnlineRecord.getOnline().equals(OnlineConstant.ON_LINE)){
                DmcDeviceAlert dmcDeviceAlert = new DmcDeviceAlert();
                dmcDeviceAlert.setDeviceNo(dmcDeviceOnlineRecord.getDeviceNo());
                dmcDeviceAlert.setIsHandle(false);

                //查询是否存在离线报警
                List<DmcDeviceAlert> alertList = dmcDeviceAlertService.select(dmcDeviceAlert);
                if(PublicUtil.isNotEmpty(alertList)){
                    //记录更新信息
                    int result=0;

                    //设备离线报警类型码
                    ArrayList<Integer> alertTypeList = new ArrayList<>();
                    alertTypeList.add(DmcDeviceAlertTypeEnum.CSUN_SLEEP_OFF_LINE.getKey());
                    alertTypeList.add(DmcDeviceAlertTypeEnum.CSUN_CAMERA_OFF_LINE.getKey());
                    alertTypeList.add(DmcDeviceAlertTypeEnum.CSUN_BODYSENSOR_OFF_LINE.getKey());
                    alertTypeList.add(DmcDeviceAlertTypeEnum.CSUN_GATEWAY_OFF_LINE.getKey());
                    alertTypeList.add(DmcDeviceAlertTypeEnum.CSUN_HUMIDISTAT_OFF_LINE.getKey());

                    //更新离线报警
                    for(DmcDeviceAlert alert:alertList) {
                        if(alertTypeList.contains(alert.getAlertType())) {
                            alert.setHandleStatus(1);
                            alert.setHandleRemark("设备已上线");
                            alert.setIsRead(true);
                            alert.setIsHandle(true);
                            /**
                             * @author  chisj
                             * @date    2020-11-19
                             * @desc    处理时间为当前时间
                             */
                            alert.setUpdateTime(new Date());
                            result += dmcDeviceAlertService.update(alert);
                        }
                    }

                    //有更新则推送信息
                    if(result>0){
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Thread.sleep(1000);
                                }catch (InterruptedException e){
                                    e.printStackTrace();
                                }finally {
                                    try{
                                        webSocketUtils.pushWebsocketMessageWithAlertLift(alertList.get(0));
                                    }catch (Exception e){
                                        log.error("web socket send message error ====> ", e.getMessage());
                                    }
                                }
                            }
                        }).start();

                        //推送信息
                        List<String> tagList = Lists.newArrayList();
                        tagList.add("deviceNo_"+alertList.get(0).getDeviceNo());

                        Map<String, Object> map = Maps.newHashMap();
                        map.put("msgType", "deviceAlertLiftMsg");

                        jPushService.sendToAll(cmnyMessageSource.getMessage("device.alert.lift.msg",null),
                                cmnyMessageSource.getMessage("device.alert.lift.msg",null),
                                cmnyMessageSource.getMessage("device.alert.lift.msg",null),
                                JSONObject.fromObject(map).toString(),
                                tagList);
                    }
                }

            }

            int insert = dmcDeviceOnlineRecordMapper.insert(dmcDeviceOnlineRecord);
            return insert;
        }
        return 0;
    }

    /**
     * 根据设备Id删除在离线记录
     *
     * @param deviceId the device id
     * @return the int.
     */
    @Override
    public Integer deleteByDeviceId(Long deviceId) {

        DmcDeviceOnlineRecord dmcDeviceOnlineRecord = new DmcDeviceOnlineRecord();
        dmcDeviceOnlineRecord.setDeviceId(deviceId);

        return delete(dmcDeviceOnlineRecord);
    }
}
